package com.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDto;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dto.PageDTO;
import com.exceptions.UpLoadFailedException;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mapper.CollectDiscoveryMapper;
import com.mapper.CommentMapper;
import com.mapper.DiscoveryMapper;
import com.mapper.LoveDiscoveryMapper;
import com.po.*;
import com.query.DiscoveryQuery;
import com.query.PageQuery;
import com.service.*;
import com.utils.AliOssUtil;
import com.vo.DiscoveryPageVo;
import com.vo.DiscoveryVo;
import com.vo.ItemPageVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @param
 * @return
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DiscoveryImpl extends ServiceImpl<DiscoveryMapper, Discovery> implements DiscoveryService{

    private final CommentService commentService;

    private final AliOssUtil aliOssUtil;

    private final UserService userService;
    private final DiscoveryMapper discoveryMapper;

    private final LoveDiscoveryService loveDiscoveryService;

    private final LoveDiscoveryMapper loveDiscoveryMapper;

    private final CollectDiscoveryMapper collectDiscoveryMapper;

    private final CollectDiscoveryService collectDiscoveryService;

    private final CommentMapper commentMapper;


    @Transactional
    @Override
    public void saveDiscovery(List<MultipartFile> image, List<MultipartFile> video, List<String> iclazz, String idescribe,String title) {
        Discovery discovery=new Discovery();
        //图片和视频上传阿里云
        List<String>images=new ArrayList<>();
        List<String>videos=new ArrayList<>();
        String filePath="";
        if (CollUtil.isNotEmpty(image)){
            for (MultipartFile file:image){
                try {
                    //原始文件名
                    String originalFilename = file.getOriginalFilename();
                    String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
                    String objectname = UUID.randomUUID().toString() + extention;
                    filePath = aliOssUtil.upload(file.getBytes(), objectname);
                    images.add(filePath);
                }catch (Exception e){
                    throw new UpLoadFailedException("文件上传失败！");
                }
            }
        }
        if (CollUtil.isNotEmpty(video)){
          for (MultipartFile file:video){
              try {
                  //原始文件名
                  String originalFilename = file.getOriginalFilename();
                  String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
                  String objectname = UUID.randomUUID().toString() + extention;
                  filePath = aliOssUtil.upload(file.getBytes(), objectname);
                  videos.add(filePath);
              }catch (Exception e){
                  throw new UpLoadFailedException("文件上传失败！");
              }
          }
      }
        //images和videos和clazz转为json字符串存入数据库
        discovery.setImage(JSON.toJSONString(images));
        discovery.setIclazz(JSON.toJSONString(iclazz));
        discovery.setVideo(JSON.toJSONString(videos));
        discovery.setUserId(StpUtil.getLoginIdAsLong());
        discovery.setIdescribe(idescribe);
        discovery.setTitle(title);
        discovery.setCreateTime(LocalDateTime.now());
        discoveryMapper.insert(discovery);
    }

    @Override
    public void like(Long id) {
        //查询是否库中是否有该帖子的点赞信息，有则删除(取消喜欢),没有则添加(喜欢)
        LambdaQueryWrapper<LoveDiscovery> eq = new LambdaQueryWrapper<LoveDiscovery>()
                .eq(LoveDiscovery::getUserId, StpUtil.getLoginIdAsLong())
                .eq(LoveDiscovery::getDiscoveryId,id);
        LoveDiscovery loveDiscovery = loveDiscoveryMapper.selectOne(eq);
        if (ObjectUtil.isEmpty(loveDiscovery)){
            log.info("用户点赞:{}",StpUtil.getLoginIdAsLong());
            LoveDiscovery loveDiscovery1=new LoveDiscovery();
            loveDiscovery1.setDiscoveryId(id);
            loveDiscovery1.setUserId(StpUtil.getLoginIdAsLong());
            loveDiscovery1.setCreateTime(LocalDateTime.now());
            loveDiscoveryService.save(loveDiscovery1);
        }else{
            log.info("用户取消点赞:{}",StpUtil.getLoginIdAsLong());
            Long id1 = loveDiscovery.getId();
            loveDiscoveryService.removeById(id1);
        }
    }

    @Override
    public void collect(Long id) {
        //查询是否库中是否有该帖子的点赞信息，有则删除(取消喜欢),没有则添加(喜欢)
        LambdaQueryWrapper<CollectDiscovery> eq = new LambdaQueryWrapper<CollectDiscovery>()
                .eq(CollectDiscovery::getUserId, StpUtil.getLoginIdAsLong())
                .eq(CollectDiscovery::getDiscoveryId,id);
        CollectDiscovery collectDiscovery = collectDiscoveryMapper.selectOne(eq);
        if (ObjectUtil.isEmpty(collectDiscovery)){
            log.info("用户收藏:{}",StpUtil.getLoginIdAsLong());
           CollectDiscovery collectDiscovery1=new CollectDiscovery();
           collectDiscovery1.setUserId(StpUtil.getLoginIdAsLong());
           collectDiscovery1.setDiscoveryId(id);
           collectDiscovery1.setCreateTime(LocalDateTime.now());
           collectDiscoveryService.save(collectDiscovery1);
        }else{
            log.info("用户取消取消收藏:{}",StpUtil.getLoginIdAsLong());
            Long id1 = collectDiscovery.getId();
            collectDiscoveryService.removeById(id1);
        }
    }

    @Override
    public void saveComment(Long id, MultipartFile image, String comments) {
        Comment comment=new Comment();
        if (ObjectUtil.isNotEmpty(image)){
            //原始文件名
            String originalFilename = image.getOriginalFilename();
            String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
            String objectname = UUID.randomUUID().toString() + extention;
            try {
                String filePath = aliOssUtil.upload(image.getBytes(), objectname);
                comment.setImage(filePath);
            } catch (IOException e) {
                throw new UpLoadFailedException("文件上传失败！");
            }
        }
        comment.setDiscoveryId(id);
        comment.setContent(comments);
        comment.setUserId(StpUtil.getLoginIdAsLong());
        comment.setCreateTime(LocalDateTime.now());
        commentService.save(comment);
    }

    @Override
    public void saveSlaveComment(Long id,Long masterId,Long slaveId, MultipartFile image, String comment) {
    Comment comment1=new Comment();
    comment1.setDiscoveryId(id);
    comment1.setRootCommentId(masterId);
    comment1.setToCommentId(slaveId);
    if (ObjectUtil.isNotEmpty(image)){
        String originalFilename = image.getOriginalFilename();
        String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
        String objectname = UUID.randomUUID().toString() + extention;
        try {
            String filePath = aliOssUtil.upload(image.getBytes(), objectname);
            comment1.setImage(filePath);
        } catch (IOException e) {
            throw new UpLoadFailedException("文件上传失败！");
        }
    }
    comment1.setContent(comment);
    comment1.setUserId(StpUtil.getLoginIdAsLong());
    comment1.setCreateTime(LocalDateTime.now());
    log.info("次级评论:{}",comment1);
    commentService.save(comment1);
    }

    @Override
    public PageDTO<DiscoveryPageVo> getDiscoveryQuery(DiscoveryQuery discoveryQuery) {
        //构建分页条件
        Page<Discovery> page = Page.of(discoveryQuery.getPageNo(),discoveryQuery.getPageSize());
        Page<Discovery> discoveryPage;
        LocalDateTime localDateTime=LocalDateTime.now();
        String sortBy = discoveryQuery.getSortBy();
        if (sortBy.equals("createTime")){
            if (discoveryQuery.getIsAsc()){
                log.info("升序");
                page.addOrder(new OrderItem("create_time",true));
            }else {
                log.info("降序");
                page.addOrder(new OrderItem("create_time",false));
            }

        }

        if(discoveryQuery.getTimeLimit()==0){
            localDateTime=LocalDateTime.now().minusDays(1);
        }else if (discoveryQuery.getTimeLimit()==1){
            localDateTime=LocalDateTime.now().minusWeeks(1);
        }else if(discoveryQuery.getTimeLimit()==2){
            localDateTime=LocalDateTime.now().minusMonths(1);
        }
        log.info("查询:{}内的图片",localDateTime);
        discoveryPage = lambdaQuery()
                .like(discoveryQuery.getTitle() != null&&discoveryQuery.getTitle()!="", Discovery::getTitle, discoveryQuery.getTitle())
                .ge(discoveryQuery.getTimeLimit()!=4L,Discovery::getCreateTime,localDateTime)
                .like(discoveryQuery.getClazz()!=null&&discoveryQuery.getClazz()!="",Discovery::getIclazz,discoveryQuery.getClazz())
                .page(page);

        PageDTO<DiscoveryPageVo> discoveryPageVoPageDto=new PageDTO<>();

        discoveryPageVoPageDto.setTotal(discoveryPage.getTotal());
        discoveryPageVoPageDto.setPages(discoveryPage.getPages());
        List<Discovery> records = discoveryPage.getRecords();
        log.info("records:{}",records);
        List<DiscoveryPageVo> discoveryPageVoList = new ArrayList<>();
        Gson gson=new Gson();
        Type listType = new TypeToken<List<String>>() {}.getType();
        if (CollUtil.isNotEmpty(records)) {
            records.forEach(record -> {
                DiscoveryPageVo discoveryPageVo=new DiscoveryPageVo();
                discoveryPageVo.setId(record.getId());
                discoveryPageVo.setUserId(record.getUserId());
                //查询喜欢数量
                LambdaQueryWrapper<LoveDiscovery> loveDiscoveryLambdaQueryWrapper=new LambdaQueryWrapper<LoveDiscovery>()
                        .eq(LoveDiscovery::getDiscoveryId,record.getId());
                Integer lovenums = loveDiscoveryMapper.selectCount(loveDiscoveryLambdaQueryWrapper);
                discoveryPageVo.setLovenums(Long.valueOf(lovenums));
                //查询收藏数量
                LambdaQueryWrapper<CollectDiscovery>collectDiscoveryLambdaQueryWrapper=new LambdaQueryWrapper<CollectDiscovery>()
                        .eq(CollectDiscovery::getDiscoveryId,record.getId());
                Integer collectnums = collectDiscoveryMapper.selectCount(collectDiscoveryLambdaQueryWrapper);
                discoveryPageVo.setCollectnums(Long.valueOf(collectnums));
                //处理视频和图片
                String image = record.getImage();
                log.info("image:{}",record.getImage());
                log.info("video:{}",record.getVideo());
                List<String> images = gson.fromJson(image, listType);
                String video=record.getVideo();
                List<String> videos = gson.fromJson(video, listType);
                log.info("video:{}",record.getVideo());
                discoveryPageVo.setImage(images);
                discoveryPageVo.setVideo(videos);
                discoveryPageVo.setTitle(record.getTitle());
                discoveryPageVoList.add(discoveryPageVo);
            });
            discoveryPageVoPageDto.setList(discoveryPageVoList);
            if (!sortBy.equals("createTime")){
                //按需求排序

                Boolean isAsc = discoveryQuery.getIsAsc();
                List<DiscoveryPageVo>result=new ArrayList<>();
                if (isAsc){
                    if (sortBy.equals("lovenums")){
                        result=discoveryPageVoList.stream().sorted(Comparator.comparing(DiscoveryPageVo::getLovenums)).collect(Collectors.toList());
                    }else if (sortBy.equals("collectnums")){
                        result=discoveryPageVoList.stream().sorted(Comparator.comparing(DiscoveryPageVo::getCollectnums)).collect(Collectors.toList());
                    }
                }else {
                    if (sortBy.equals("lovenums")){
                        result=discoveryPageVoList.stream().sorted(Comparator.comparing(DiscoveryPageVo::getLovenums).reversed()).collect(Collectors.toList());
                    }else if (sortBy.equals("collectnums")){
                        result=discoveryPageVoList.stream().sorted(Comparator.comparing(DiscoveryPageVo::getCollectnums).reversed()).collect(Collectors.toList());
                    }
                }
                discoveryPageVoPageDto.setList(result);
            }


        }
        log.info("result:{}",discoveryPageVoPageDto);
        return discoveryPageVoPageDto;
    }

    @Override
    public DiscoveryVo getDiscovery(Long id) {
        //查询帖子信息
        LambdaQueryWrapper<Discovery> wrapper=new LambdaQueryWrapper<Discovery>();
        wrapper.eq(Discovery::getId,id);
        Discovery discovery = discoveryMapper.selectOne(wrapper);
        DiscoveryVo discoveryVo=new DiscoveryVo();
        //查询作者信息
        User user = userService.getById(discovery.getUserId());
        discoveryVo.setAvatar(user.getImage());
        discoveryVo.setUserId(user.getId());
        discoveryVo.setUserName(user.getName());
        //查询收藏和喜欢数
        LambdaQueryWrapper<LoveDiscovery>loveDiscoveryLambdaQueryWrapper=new LambdaQueryWrapper<LoveDiscovery>();
        loveDiscoveryLambdaQueryWrapper.eq(LoveDiscovery::getDiscoveryId,id);
        Integer loveCount = loveDiscoveryMapper.selectCount(loveDiscoveryLambdaQueryWrapper);
        discoveryVo.setLoves(Long.valueOf(loveCount));
        LambdaQueryWrapper<CollectDiscovery>discoveryLambdaQueryWrapper=new LambdaQueryWrapper<CollectDiscovery>();
        discoveryLambdaQueryWrapper.eq(CollectDiscovery::getDiscoveryId,id);
        Integer collectNums = collectDiscoveryMapper.selectCount(discoveryLambdaQueryWrapper);
        discoveryVo.setCollection(Long.valueOf(collectNums));
        discoveryVo.setDescribe(discovery.getIdescribe());
        discoveryVo.setId(discovery.getId());
        discoveryVo.setComments(commentService.getComments(id));
        //查询评论数
        LambdaQueryWrapper<Comment> commentLambdaQueryWrapper1 = new LambdaQueryWrapper<Comment>();
        commentLambdaQueryWrapper1.eq(Comment::getDiscoveryId,id);
        Integer commentNums = commentMapper.selectCount(commentLambdaQueryWrapper1);
        discoveryVo.setCommentNums(Long.valueOf(commentNums));
        return discoveryVo;
    }
}
